﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
/**
 *NuGet安装Swashbuckle.AspNetCore 
 *NuGet安装Microsoft.AspNetCore
 * 

            // 创建 API 服务实例
            var apiService = new ApiService(
                port: 5050,
                url: "http://localhost",
                serviceName: "可控制 API 服务"
            );

            if (apiService.IsRunning)
            {
                MessageBox.Show("API 服务已在运行中。");
            }
            else
            {
                try
                {
                    apiService.StartAsync();
                    MessageBox.Show("API 服务已启动。");
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"启动 API 服务失败: {ex.Message}");
                }
            }

       //apiService.StopAsync();//停止服务示例
*/



/// <summary>
/// API 服务管理类 - 封装 API 服务的启动、停止和端点管理功能
/// </summary>
public class ApiService
{
    // Web 主机实例 - 代表整个 Web 应用程序
    private IWebHost? _host;

    // 取消令牌源 - 用于控制服务的停止
    private readonly CancellationTokenSource _cts = new();

    // 服务监听的端口号
    private readonly int _port;

    // 服务监听的基地址
    private readonly string _url;

    // 服务名称（用于日志和文档）
    private readonly string _serviceName;

    /// <summary>
    /// 构造函数 - 初始化 API 服务
    /// </summary>
    /// <param name="port">服务监听的端口号 (默认 5000)</param>
    /// <param name="url">服务监听的基地址 (默认 "http://localhost")</param>
    /// <param name="serviceName">服务名称 (默认 "API Service")</param>
    public ApiService(int port = 5000, string url = "http://localhost", string serviceName = "API Service")
    {
        _port = port;
        _url = url;
        _serviceName = serviceName;
    }




    /// <summary>
    /// 异步启动 API 服务
    /// </summary>
    /// <returns>表示异步操作的任务</returns>
    public async Task StartAsync()
    {
        // 如果服务已经启动，则直接返回
        if (_host != null)
        {
            Debug.WriteLine("服务已在运行中");
            return;
        }

        try
        {
            Debug.WriteLine("正在启动 API 服务...");

            // ===================================================================
            // 第一步：创建并配置 Web 主机
            // ===================================================================
            _host = new WebHostBuilder()
                // 使用 Kestrel 作为 Web 服务器
                .UseKestrel(options =>
                {
                    // 可以在这里配置 Kestrel 选项
                    // 例如：设置请求大小限制、保持活动连接等
                })

                // 设置服务监听的 URL
                .UseUrls($"{_url}:{_port}")

                // ===================================================================
                // 第二步：配置依赖注入容器
                // ===================================================================
                .ConfigureServices(services =>
                {
                    // 添加 MVC 控制器支持（如果需要）
                    services.AddControllers();

                    // 添加 API 端点探索服务（Swagger 所需）
                    services.AddEndpointsApiExplorer();

                    // 添加 Swagger 文档生成服务
                    services.AddSwaggerGen(c =>
                    {
                        c.SwaggerDoc("v1", new OpenApiInfo
                        {
                            Title = _serviceName,
                            Version = "v1",
                            Description = $"可控制的 {_serviceName}",
                            Contact = new OpenApiContact
                            {
                                Name = "技术支持",
                                Email = "support@example.com"
                            }
                        });

                        // 可选：包含 XML 注释文档
                        // var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                        // var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                        // c.IncludeXmlComments(xmlPath);
                    });

                  

                    // 添加跨域策略（可选）
                    services.AddCors(options =>
                    {
                        options.AddDefaultPolicy(builder =>
                        {
                            builder.AllowAnyOrigin()
                                   .AllowAnyMethod()
                                   .AllowAnyHeader();
                        });
                    });
                })

                // ===================================================================
                // 第三步：配置请求处理管道（中间件）
                // ===================================================================
                .Configure(app =>
                {
                    // 获取当前环境（开发/生产）
                    var env = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();

                    // 如果是开发环境，启用开发者异常页面和 Swagger
                    if (env.IsDevelopment())
                    {
                        // 显示详细的错误信息
                        app.UseDeveloperExceptionPage();

                        // 启用 Swagger JSON 端点
                        app.UseSwagger();

                        // 启用 Swagger UI
                        app.UseSwaggerUI(c =>
                        {
                            c.SwaggerEndpoint("/swagger/v1/swagger.json", $"{_serviceName} v1");
                            c.RoutePrefix = "swagger"; // 设置 UI 访问路径
                            c.DocumentTitle = $"{_serviceName} 文档";
                        });
                    }
                    else
                    {
                        // 生产环境：添加全局错误处理
                        app.UseExceptionHandler("/error");
                    }

                    // 启用 HTTPS 重定向（推荐）
                    app.UseHttpsRedirection();

                    // 启用静态文件服务（可选）
                    // app.UseStaticFiles();

                    // 启用路由
                    app.UseRouting();

                    // 启用跨域策略（如果配置了 CORS）
                    app.UseCors();

                    // 启用认证和授权（可选）
                    // app.UseAuthentication();
                    // app.UseAuthorization();

                    // 配置端点
                    app.UseEndpoints(endpoints =>
                    {
                        // ===================================================================
                        // 第四步：配置 API 端点
                        // ===================================================================

                        // 1. 服务状态端点
                        endpoints.MapGet("/status", () =>
                        {
                            return Results.Ok(new
                            {
                                Service = _serviceName,
                                Status = "Running",
                                Timestamp = DateTime.UtcNow,
                                Version = "1.0.0"
                            });
                        })
                        .WithName("GetServiceStatus")
                        .WithTags("System")
                        .Produces(StatusCodes.Status200OK, contentType: "application/json");


                        //数据接收端点(POST)
                        endpoints.MapPost("/api/data/receive", async (HttpContext context) =>
                        {
                            try
                            {
                                // 从请求体读取数据
                                using var reader = new StreamReader(context.Request.Body);
                                var json = await reader.ReadToEndAsync();

                                // 解析 JSON 数据
                                var data = JsonSerializer.Deserialize<Dictionary<string, object>>(json);

                                if (data == null || data.Count == 0)
                                {
                                    return Results.BadRequest("无效的数据格式");
                                }

                                // 创建接收数据记录
                                var received = new ReceivedData
                                {
                                    Id = Guid.NewGuid(),
                                    Timestamp = DateTime.UtcNow,
                                    RemoteIp = context.Connection.RemoteIpAddress?.ToString() ?? "未知",
                                    Data = data
                                };


                                // 打印到控制台--------------------------------------------------------------------------------------
                                PrintReceivedData(received);

                                return Results.Ok(new
                                {
                                    Message = "数据接收成功",
                                    Id = received.Id,
                                    Timestamp = received.Timestamp
                                });
                            }
                            catch (JsonException ex)
                            {
                                return Results.Problem(
                                    title: "JSON 解析错误",
                                    detail: ex.Message,
                                    statusCode: StatusCodes.Status400BadRequest
                                );
                            }
                            catch (Exception ex)
                            {
                                return Results.Problem(
                                    title: "服务器错误",
                                    detail: ex.Message,
                                    statusCode: StatusCodes.Status500InternalServerError
                                );
                            }
                        })
                        .Accepts<Dictionary<string, object>>("application/json")
                        .Produces(StatusCodes.Status200OK)
                        .ProducesProblem(StatusCodes.Status400BadRequest)
                        .ProducesProblem(StatusCodes.Status500InternalServerError)
                        .WithName("ReceiveData")
                        .WithTags("Data");



                        // 3. 数据发送端点 (GET)
                        endpoints.MapGet("/api/data/send", () =>
                        {
                            // 创建示例数据
                            var data = new Dictionary<string, object>
                            {
                                ["Message"] = "这是来自服务器的数据",
                                ["DateTime"] = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"),
                                ["JavaScriptTime"]= ConvertDateTimeToJavaScriptTimestamp(DateTime.Now),
                                ["Items"] = new List<object>
                                {
                                    new { id = 1, name = "项目A", value = new Random().Next(0,500) },
                                    new { id = 2, name = "项目B", value = new Random().Next(50,1000) }
                                },
                                ["Metadata"] = new
                                {
                                    version = "1.0",
                                    generatedBy = _serviceName
                                }
                            };

                            return Results.Ok(data);
                        })
                        .Produces<Dictionary<string, object>>(StatusCodes.Status200OK, contentType: "application/json")
                        .WithName("SendData")
                        .WithTags("Data");























                        // 如果需要 MVC 控制器
                        // endpoints.MapControllers();
                    });
                })
                .Build(); // 构建 WebHost 实例

            // ===================================================================
            // 第四步：启动服务
            // ===================================================================
            await _host.StartAsync(_cts.Token);

            Debug.WriteLine($"{_serviceName} 已成功启动");
            Debug.WriteLine($"服务地址: {_url}:{_port}");

        }
        catch (Exception ex)
        {
            Debug.WriteLine($"启动服务时出错: {ex.Message}");
            _host?.Dispose();
            _host = null;
            throw;
        }
    }

    /// <summary>
    /// 时间转换
    /// </summary>
    /// <param name="dateTime"></param>
    /// <returns></returns>
    private long ConvertDateTimeToJavaScriptTimestamp(DateTime dateTime)
    {
        TimeZoneInfo localZone = TimeZoneInfo.Local;
        DateTimeOffset localOffset = new DateTimeOffset(dateTime, localZone.GetUtcOffset(dateTime));
        long timestamp = (long)(localOffset.ToUnixTimeMilliseconds());
        return timestamp;
    }

    /// <summary>
    /// 异步停止 API 服务
    /// </summary>
    /// <param name="timeoutSeconds">停止超时时间（秒），默认 5 秒</param>
    /// <returns>表示异步操作的任务</returns>
    public async Task StopAsync(int timeoutSeconds = 5)
    {
        // 如果服务未启动，则直接返回
        if (_host == null)
        {
            Debug.WriteLine("服务未运行");
            return;
        }

        try
        {
            Debug.WriteLine("正在停止 API 服务...");

            // 发送取消信号 - 通知服务停止
            _cts.Cancel();

            // 等待服务停止（带超时）
            await _host.StopAsync(TimeSpan.FromSeconds(timeoutSeconds));

            Debug.WriteLine($"{_serviceName} 已成功停止");
        }
        catch (OperationCanceledException)
        {
            // 正常取消操作，忽略异常
            Debug.WriteLine("服务已响应停止请求");
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"停止服务时出错: {ex.Message}");
        }
        finally
        {
            // 确保释放资源
            _host.Dispose();
            _host = null;
            Debug.WriteLine("服务资源已释放");
        }
    }

    /// <summary>
    /// 检查 API 服务是否正在运行
    /// </summary>
    public bool IsRunning => _host != null;

    /// <summary>
    /// 获取服务地址
    /// </summary>
    public string ServiceUrl => $"{_url}:{_port}";

    /// <summary>
    /// 获取 Swagger 文档地址
    /// </summary>
    public string SwaggerUrl => $"{_url}:{_port}/swagger";


    /// <summary>
    /// 打印接收到的数据到控制台
    /// </summary>
    private void PrintReceivedData(ReceivedData data)
    {
        
        Debug.WriteLine("===== 接收到新数据 =====");
        Debug.WriteLine($"时间: {data.Timestamp:yyyy-MM-dd HH:mm:ss.fff}");
        Debug.WriteLine($"来源: {data.RemoteIp}");
        Debug.WriteLine($"数据ID: {data.Id}");



        //items中内容为json,并转dictionary
        if (data.Data.TryGetValue("items", out object itemsObj) && itemsObj is JsonElement itemsElement)
        {
            Dictionary<string, object> itemsDict = new Dictionary<string, object>();
            foreach (var prop in itemsElement.EnumerateObject())
            {

                // 根据JSON元素类型获取对应的值
                itemsDict[prop.Name] = (prop.Value);
            }
            Debug.WriteLine(itemsDict["a"]);
        }

        // 打印JSON数据（格式化的）
        Debug.WriteLine("数据内容:");
        var jsonOptions = new JsonSerializerOptions { WriteIndented = true };
        var json = JsonSerializer.Serialize(data.Data, jsonOptions);

        Debug.WriteLine(json);

        Debug.WriteLine("=======================");
       
    }

    /// <summary>
    /// 接收到的数据结构
    /// </summary>
    private class ReceivedData
    {
        public Guid Id { get; set; }
        public DateTime Timestamp { get; set; }
        public string RemoteIp { get; set; } = "未知";
        public Dictionary<string, object> Data { get; set; } = new();
    }

}